//#include "StdAfx.h"
#include "BasicHideWndMessage.h"
#include <Windows.h>
#include <WinUser.h>
#include <tchar.h>

//extern HINSTANCE g_hInstance;
namespace utility
{
	BasicHideWndMessage::BasicHideWndMessage(void)
		: m_hwnd(NULL)
		, m_hThread(NULL)
		, m_hInstance(NULL)
		, m_wndProc(MessageWndProc)
		, m_strClassName(_T("BasicMessageWindowClass"))
		, m_strWindowName(_T("BasicMessageWindowName"))
	{
	}

	BasicHideWndMessage::~BasicHideWndMessage(void)
	{
	}

	
	LRESULT CALLBACK BasicHideWndMessage::MessageWndProc(
		HWND hWnd,              // handle to window
		UINT Msg,               // message
		WPARAM wParam,          // first message parameter
		LPARAM lParam           // second message parameter
		)
	{
		switch(Msg)
		{
		case WM_CLOSE:
			DestroyWindow(hWnd);
			break;
		case WM_DESTROY:
			PostQuitMessage(0);
			break;
		case (WM_USER+10001):
			//OutputDebugString(_T("xxm: case (WM_USER+10001): \r\n"));
			break;
		case WM_SETTINGCHANGE:
			OutputDebugString(_T("xxm: WM_SETTINGCHANGE  \r\n"));
			break;
		default:
			return DefWindowProc(hWnd,Msg,wParam,lParam);
		}
		return 0;
	}

	bool BasicHideWndMessage::InitMessageWindow( HINSTANCE hInstanceEx )
	{
		if( m_hwnd )
		{
			return true;
		}

		HINSTANCE hInstance = NULL;

		if( hInstanceEx )
		{
			hInstance = hInstanceEx;
		}else
		{
			hInstance = GetModuleHandle(NULL);//hInstanceEx;
		}

		if (hInstance == NULL)
		{
			//OutputDebugString(_T("xxm:hInstance == NULL\r\n"));
			return false;
		}

		// Register the main window class. 
		WNDCLASS wc; 
		
		wc.style = CS_HREDRAW | CS_VREDRAW; 
		wc.lpfnWndProc = (WNDPROC) m_wndProc/*MessageWndProc*/; 
		wc.cbClsExtra = 0; 
		wc.cbWndExtra = 0; 
		wc.hInstance = hInstance;//g_hInstance
		wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); 
		wc.hCursor = LoadCursor(NULL, IDC_ARROW); 
		wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); 
		wc.lpszMenuName =  m_strWindowName.c_str(); 
		wc.lpszClassName = m_strClassName.c_str(); 

		if (!RegisterClass(&wc)) 
		{
			return false; 
		}

		//creat window
		m_hwnd = CreateWindowEx(0,m_strClassName.c_str(), m_strWindowName.c_str(),0,0,0,0,0,HWND_MESSAGE,0, hInstance /*g_hInstance*/,0 );
		//m_hwnd = CreateWindow(_T("MessageWindowClass"), _T("MessageWindowClass"),WS_OVERLAPPEDWINDOW,0,0,0,0,NULL,NULL,g_hInstance,NULL);

		if (m_hwnd == NULL)
		{
			//OutputDebugStringA("xxm:CreateWindowEx fail\n");
			return false; 
		}

		
		return true;
	}

	void BasicHideWndMessage::DestroyMessageWindow()
	{
		
		if( m_hwnd )
		{
			::PostMessage(m_hwnd,WM_DESTROY, NULL, NULL);
			m_hwnd = NULL;
		}

		if( m_hThread )
		{
			if( WaitForSingleObject( m_hThread, 5000 ) != WAIT_OBJECT_0 )
			{
				TerminateThread( m_hThread, -1 );
			}
			CloseHandle(m_hThread);
			m_hThread = NULL;
		}
	}

	bool BasicHideWndMessage::CreateMessageWindow( bool bThread )
	{
		if( bThread )
		{
			m_hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)MessageThreadProc, this, 0, &m_dwThreadID);
			return (m_hThread!=NULL);
		}else
		{
			return this->InitMessageWindow(m_hInstance);
		}

	}

	DWORD WINAPI BasicHideWndMessage::MessageThreadProc( LPDWORD lpdwParam )
	{

		//OutputDebugString(_T("xxm: MessageThreadProc \r\n"));
		BasicHideWndMessage *pThis = reinterpret_cast<BasicHideWndMessage*>(lpdwParam);

		if( !pThis ) 
		{
			return 0;
		}


		if( !pThis->InitMessageWindow(pThis->m_hInstance) )
		{
			return 0;
		}

		::ShowWindow(pThis->m_hwnd, SW_HIDE);
		::UpdateWindow(pThis->m_hwnd);
		
		#define IDC_DOINSTAPK			209
		HACCEL hAccelTable;
		hAccelTable = LoadAccelerators(pThis->m_hInstance, MAKEINTRESOURCE(IDC_DOINSTAPK));

		MSG msg;
		BOOL bRet;

		while ((bRet = ::GetMessage(&msg, NULL, 0, 0)))
		{
			/*if (msg.message == (WM_USER+10001))
			{
				OutputDebugStringA("xxm:receive msg\n");
			}*/

			if (!::TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
			{
				::TranslateMessage(&msg);
				::DispatchMessage(&msg);
			}
		}

		//pThis->DestroyMessageWindow();

		return 0;
	}

	void BasicHideWndMessage::SethInstance( HINSTANCE hInstance )
	{
		if( hInstance )
		{
			m_hInstance = hInstance;
		}
	}

	void BasicHideWndMessage::SetWndProc( WNDPROC wndProc )
	{
		if( wndProc )
		{
			m_wndProc = wndProc;
		}
	}

	void BasicHideWndMessage::SetWindowAttribute( cstr_t strClassName, cstr_t strWindowName )
	{
		if( strClassName )
		{
			m_strClassName = strClassName;
		}

		if( strWindowName )
		{
			m_strWindowName = strWindowName;
		}
	}
}

